/*
 * 功能：用于生成和解析JWT Token
 * 作者：张杨(Sunny)
 * 日期： 2024/10/26 上午11:22
 */
package com.example.springboot.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.springboot.entity.User;
import com.example.springboot.mapper.UserMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;


/**
 * token 工具类，用于生成和解析JWT Token
 */
@Component
public class TokenUtils {

    private static UserMapper staticUserMapper;

    @Resource
    UserMapper userMapper;


    /**
     * 初始化 userMapper 赋值给 staticUserMapper ，以便在静态方法中使用
     */
    @PostConstruct
    public void setUserService() {
        staticUserMapper = userMapper;
    }


    /**
     * 生成 token
     *
     * @param userId 用户ID
     * @param sign   签名
     * @return 生成的JWT Token
     */
    public static String createToken(String userId, String sign){
        return JWT.create().withAudience(userId). // 将 userid 保存到 token 作为载荷
                withExpiresAt(DateUtil.offsetHour(new Date(), 1)) // 1小时后 token 过期
                .sign(Algorithm.HMAC256(sign)); // 使用签名算法HMAC256和提供的签名生成Token
    }


    /**
     * 获取当前登录的用户信息
     *
     * @return 当前登录的用户信息，如果没有登录或者token无效则返回null
     */
    public static User getCurrentUser(){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes()).getRequest(); // 获取当前请求
            String token = request.getHeader("token"); // 从请求头中获取Token

            if (StrUtil.isNotBlank(token)){
                // 解析Token获取用户ID
                String userId = JWT.decode(token).getAudience().get(0);
                // 根据用户ID查询用户信息
                return staticUserMapper.selectById(Integer.valueOf(userId));
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
